package net.lzzy.practices.web.courses;

import io.swagger.annotations.Api;
import net.lzzy.practices.constants.ApiConstant;
import net.lzzy.practices.constants.Messages;
import net.lzzy.practices.entities.Applicant;
import net.lzzy.practices.entities.Course;
import net.lzzy.practices.services.ApplicantService;
import net.lzzy.practices.utils.StringUtil;
import net.lzzy.practices.web.models.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.IllegalFormatException;
import java.util.List;
import java.util.UUID;

/**
 * @author 1
 */
@RestController
@CrossOrigin
@RequestMapping(ApiConstant.ROUTE_APPLY_ROOT)
public class ApplicontApiController {
    private final ApplicantService service;

    @Autowired
    public ApplicontApiController(ApplicantService service) {
        this.service = service;
    }

    @PostMapping(ApiConstant.ROUTE_APPLY_APPLY)
    public ApiResult apply(@RequestBody ApplicantInfo info) {
        String token = info.getToken();
        String strCourseId = info.getCourseId();
        String serStudentId = info.getStudentId();
        if (StringUtil.isEmpty(token) || StringUtil.isEmpty(strCourseId) || StringUtil.isEmpty(serStudentId)) {
            return new ApiResult(false, Messages.MISS_ARGS.toString(), null);
        }
        try {
            UUID studentId = UUID.fromString(serStudentId);
            UUID courseId = UUID.fromString(strCourseId);
            Applicant applicant = service.apply(studentId, courseId, token);
            if (applicant == null) {
                return new ApiResult(false, Messages.WRONG_ID.toString(), null);
            }
            return new ApiResult(true, Messages.SUCCESS.toString(), new VmApplicant(applicant));
        } catch (IllegalFormatException e) {
            return new ApiResult(false, Messages.WRONG_ID.toString(), null);
        }
    }

    @GetMapping(ApiConstant.ROUTE_APPLY_STUONT_COURSES)
    public ApiResult getStudentApplicants(@RequestParam(name = "id") UUID studentId, String token) {
        List<Applicant> applicants = service.getAllCourses(studentId, token);
        return transform(applicants);
    }

    private static ApiResult transform(List<Applicant> applicants) {
        if (applicants == null) {
            return new ApiResult(false, Messages.NO_PERMISSION.toString(), null);
        }
        List<VmApplicant> vmApplicants = new ArrayList<>();
        applicants.forEach(applicant -> vmApplicants.add(new VmApplicant(applicant)));
        return new ApiResult(true, applicants.size() + "", vmApplicants);
    }

    @GetMapping(ApiConstant.ROUTE_APPLY_STUONT_ENROLLED)
    public ApiResult getEnrolledApplicants(@RequestParam(name = "id") UUID studentId, @RequestParam String token) {
        List<Applicant> applicants = service.getEnrolledCourses(studentId, token);
        return transform(applicants);
    }
    @GetMapping(ApiConstant.ROUTE_APPLY_STUONT_APPLYING)
    public ApiResult getApplyingApplicants(@RequestParam(name = "id") UUID studentId, @RequestParam String token) {
        List<Applicant> applicants = service.getApplyingCourses(studentId, token);
        return transform(applicants);
    }
    @GetMapping(ApiConstant.ROUTE_APPLY_STUONT_DECLINED)
    public ApiResult getDeclinedApplicants(@RequestParam(name = "id") UUID studentId, @RequestParam String token) {
        List<Applicant> applicants = service.getDeclinedCourses(studentId, token);
        return transform(applicants);
    }
    @PostMapping(ApiConstant.ROUTE_APPLY_APPROVE)
    public ApiResult approve(@RequestBody ApproveInfo info){
        String token = info.getToken();
        String strApplicantId = info.getApplicantId();
        if (StringUtil.isEmpty(token) || StringUtil.isEmpty(strApplicantId)) {
            return new ApiResult(false, Messages.MISS_ARGS.toString(), null);
        }
        try {
            UUID applicantId = UUID.fromString(strApplicantId);
            Applicant applicant = service.approve(applicantId, token);
            if (applicant == null) {
                return new ApiResult(false, Messages.NO_PERMISSION.toString(), null);
            }
            return new ApiResult(true, Messages.SUCCESS.toString(), new VmApplicant(applicant));
        }catch (IllegalFormatException e) {
            return new ApiResult(false, Messages.WRONG_ID.toString(), null);
        }
    }
    @PostMapping(ApiConstant.ROUTE_APPLY_DECLINE)
    public ApiResult decline(@RequestBody ApproveInfo info){
        String token = info.getToken();
        String strApplicantId = info.getApplicantId();
        if (StringUtil.isEmpty(token) || StringUtil.isEmpty(strApplicantId)) {
            return new ApiResult(false, Messages.MISS_ARGS.toString(), null);
        }
        try {
            UUID applicantId = UUID.fromString(strApplicantId);
            Applicant applicant = service.decline(applicantId, token);
            if (applicant == null) {
                return new ApiResult(false, Messages.NO_PERMISSION.toString(), null);
            }
            return new ApiResult(true, Messages.SUCCESS.toString(), new VmApplicant(applicant));
        }catch (IllegalFormatException e) {
            return new ApiResult(false, Messages.WRONG_ID.toString(), null);
        }
    }
    @GetMapping(ApiConstant.ROUTE_APPLY_TEACHER_APPLYING)
    public ApiResult getApplyingStudents(@RequestParam(name = "id") UUID courseId,@RequestParam String token) {
        List<Applicant> applicants = service.getApplyingStudents(courseId, token);
        return transform(applicants);
    }
    @GetMapping(ApiConstant.ROUTE_APPLY_TEACHER_ENROLLED)
    public ApiResult getEnrolledStudents(@RequestParam(name = "id") UUID courseId,@RequestParam String token) {
        List<Applicant> applicants = service.getEnrolledStudents(courseId, token);
        return transform(applicants);
    }
    @GetMapping(ApiConstant.ROUTE_APPLY_TEACHER_DECLINED)
    public ApiResult getDeclinedStudents(@RequestParam(name = "id") UUID courseId,@RequestParam String token) {
        List<Applicant> applicants = service.getDeclinedStudents(courseId, token);
        return transform(applicants);
    }
    @PostMapping(ApiConstant.ROUTE_APPLY_REMOVE)
    public ApiResult remove(@RequestBody ApplicantInfo info){
        String token = info.getToken();
        String strCourseId = info.getCourseId();
        String strStudentId = info.getStudentId();
        if (StringUtil.isEmpty(token) || StringUtil.isEmpty(strCourseId) || StringUtil.isEmpty(strStudentId)) {

            return new ApiResult(false, Messages.MISS_ARGS.toString(), null);
        }
        try {
            UUID courseId = UUID.fromString(strCourseId);
            UUID studentId = UUID.fromString(strStudentId);
            Course course = service.removeStudent(courseId,studentId,token);
            if (course == null) {
                return new ApiResult(false, Messages.NO_PERMISSION.toString(), null);
            }
            return new ApiResult(true, Messages.SUCCESS.toString(),VmCourse.create(course,true));
        }catch (IllegalFormatException e){
            return new ApiResult(false,Messages.WRONG_ID.toString(), null);
        }
    }

}
//控制器方法有哪些注解   GetMapping/PostMapping和RequestParam/RequestBody
//控制器类注解  RestController/RequestMapping/CrossOrigin
//构造注解@Autowired
